# -*- makefile -*-
# vi:se ft=make:

include $(srcdir)/Modules.generic

# UTEST depends on KERNEL and CHECKSUM, must be listed after them
SUBSYSTEMS := $(filter-out UTEST,$(SUBSYSTEMS)) BOOT CHECKSUM SYMBOLS GBLCFG \
              $(filter UTEST,$(SUBSYSTEMS))

PREPROCESS_PARTS 	+= arch $(CONFIG_ABI) 32bit iofp recover_jmpbuf \
			   $(CONFIG_XARCH) apic i8259 pc i8254 fpu \
			   abs_syscalls auto_map_kip io realmode libuart

PREPROCESS_PARTS-$(CONFIG_MP)                += need_xcpu_tlb_flush
PREPROCESS_PARTS-$(CONFIG_JDB)               += debug log
PREPROCESS_PARTS-$(CONFIG_SCHED_PIT)         += pit_timer
PREPROCESS_PARTS-$(CONFIG_SCHED_RTC)         += rtc_timer
PREPROCESS_PARTS-$(CONFIG_SCHED_APIC)        += apic_timer
PREPROCESS_PARTS-$(CONFIG_SCHED_HPET)        += hpet_timer
PREPROCESS_PARTS-$(CONFIG_CPU_VIRT)          += svm vmx virtual_space_iface
PREPROCESS_PARTS-$(CONFIG_IOMMU)             += virtual_space_iface

PREPROCESS_PARTS        += $(PREPROCESS_PARTS-y)

#
# TYPES subsystem
#
PRIVATE_INCDIR		+= types/$(CONFIG_XARCH) types

#
# ABI Subsystem
#
INTERFACES_ABI		+= virt

kip_IMPL		+= kip-ia32-debug
virt_IMPL		:= virt-ia32

#
# JABI Subsystem
#
JABI			:= libjabi.a
VPATH			+= jabi/$(CONFIG_XARCH) jabi
INTERFACES_JABI		:= jdb_ktrace jdb_obj_info

VPATH_LIBUART  := $(srcdir)/lib/uart
PRIVATE_INCDIR += lib/uart
SUBSYSTEMS += LIBUART
LIBUART			:= uart/libuart.a
OBJECTS_LIBUART = uart_16550.o

#
# DRIVERS subsystem
#
DRIVERS			:= libdrivers.a libgluedriverslibc.a
VPATH			+= drivers/$(CONFIG_XARCH) drivers
PRIVATE_INCDIR		+= drivers/$(CONFIG_XARCH) drivers
INTERFACES_DRIVERS	:= mux_console console keyb io pci vga_console reset \
			   processor delayloop mem
ifeq ("$(CONFIG_SERIAL)","y")
INTERFACES_DRIVERS	+= filter_console uart
INTERFACES_DRIVERS	+= $(if $(CONFIG_UART_CHECKSUM),stream_crc32)
endif
INTERFACES_DRIVERS      += fb_console
reset_IMPL		:= reset-ia32
uart_IMPL		:= uart uart-libuart
CXXFLAGS_uart-libuart   := $(call LIBUART_UART, 16550)
CXXFLAGS_uart-libuart   += -DUART_16550_INIT_MCR=0x08
CXXSRC_DRIVERS		:= glue_libc.cc
NOOPT			+= $(patsubst %.o, %, $(OBJ_DRIVERS))

keyb_IMPL		:= keyb keyb-pc 
io_IMPL			:= io io-ia32
mem_IMPL		:= mem mem-ia32
processor_IMPL		:= processor processor-ia32

#
# FONTS subsystem
#
SUBSYSTEMS		+= FONTS
FONTS			:= libfonts.a
FONT_FILES		:= vgafont.psf
VPATH			+= ../data/fonts
OBJ_FONTS		:= $(addsuffix .bin.o,$(FONT_FILES))
NOOPT			+= $(patsubst %.o, %, $(OBJ_FONTS))
KERNEL_EXTRA_LIBS	+= $(FONTS)

#
# KERNEL subsystem
#
KERNEL			:= fiasco.debug
VPATH			+= kern/$(CONFIG_XARCH) kern/ia32/32 kern/ia32 kern
VPATH			+= jdb/ia32/32 jdb/ia32 jdb
PRIVATE_INCDIR		+= kern/$(CONFIG_XARCH) kern/ia32/32 kern/ia32 kern

INTERFACES_KERNEL	+= __main acpi acpi_fadt acpi_dmar i8259 \
			   irq_chip_ia32 irq_chip_pic \
			   io_apic intel_iommu io_apic_remapped \
			   boot_console \
			   irq_msi io_space apic pit boot_info checksum \
			   x86desc gdt idt tss timer_irq dirq allocator \
			   alternatives

INTERFACES_KERNEL-$(CONFIG_IOMMU)    += intel_dmar dmar_space
INTERFACES_KERNEL-$(CONFIG_CPU_VIRT) += svm vmx vm vm_svm vm_vmx vm_vmx_ept

alternatives_IMPL	:= alternatives alternatives-ia32
apic_IMPL		:= apic-ia32 apic-ia32-mp
boot_console_IMPL	:= boot_console-ia32
boot_info_IMPL		:= boot_info boot_info-ia32
clock_IMPL              := clock clock-ia32
config_IMPL		:= config config-ia32-32 config-ia32
context_IMPL		:= context context-ia32 context-ia32-32 context-vcpu
continuation_IMPL	:= continuation-ia32-32
cpu_IMPL		:= cpu cpu-ia32 cpu-32
dirq_IMPL		:= dirq-ia32
entry_frame_IMPL	:= entry_frame entry_frame-ia32
fpu_IMPL		:= fpu fpu-ia32
ipi_IMPL		:= ipi ipi-ia32
kdb_ke_IMPL		+= kdb_ke-ia32
kernel_thread_IMPL	:= kernel_thread kernel_thread-ia32
kernel_uart_IMPL	:= kernel_uart kernel_uart-libuart
kip_init_IMPL		:= kip_init-ia32
kmem_IMPL		:= kmem kmem-ia32 kmem-ia32-32
kmem_alloc_IMPL		:= kmem_alloc kmem_alloc-ia32
main_IMPL		:= main-ia32-32 main-ia32
map_util_IMPL		:= map_util map_util-mem map_util-io map_util-objs
mem_layout_IMPL		:= mem_layout mem_layout-ia32 mem_layout-ia32-32
mem_space_IMPL		:= mem_space mem_space-user mem_space-ia32
mem_unit_IMPL		:= mem_unit-ia32
page_IMPL		:= page page-ia32
paging_IMPL		:= paging paging-ia32-32 paging-ia32
perf_cnt_IMPL		:= perf_cnt perf_cnt-ia32
pic_IMPL		:= pic pic-i8259
pit_IMPL		:= pit-i8254
platform_control_IMPL	+= platform_control-acpi_sleep platform_control-ia32
rtc_IMPL		:= rtc-ia32
sched_context_IMPL	:= sched_context-wfq sched_context-fixed_prio \
			   sched_context-fp_wfq sched_context
sigma0_task_IMPL	:= sigma0_task sigma0_task-io
space_IMPL		:= space space-ia32 space-io
spin_lock_IMPL		:= spin_lock spin_lock-ia32
startup_IMPL		:= startup startup-ia32
sys_call_page_IMPL	:= sys_call_page sys_call_page-abs-ia32
task_IMPL		:= task task-ia32
tb_entry_IMPL		:= tb_entry tb_entry-ia32-32
timer_IMPL		:= timer timer-ia32
thread_IMPL		:= thread thread-ia32 thread-ia32-32 \
			   thread-ipc thread-pagefault thread-log \
			   thread-debug thread-dbf thread-vcpu thread-io
utcb_init_IMPL		:= utcb_init utcb_init-ia32
vmem_alloc_IMPL		:= vmem_alloc vmem_alloc-ia32
watchdog_IMPL		:= watchdog watchdog-ia32

INTERFACES_KERNEL-$(CONFIG_SERIAL) += uart_console

cpu_lock_IMPL		:= cpu_lock cpu_lock-generic

ifeq ("$(CONFIG_SCHED_PIT)","y")
  timer_IMPL		+= timer-pit
  timer_tick_IMPL	+= timer_tick-single-vector timer_tick-ia32
endif
ifeq ("$(CONFIG_SCHED_RTC)","y")
  timer_IMPL		+= timer-rtc
  timer_tick_IMPL	+= timer_tick-single-vector timer_tick-ia32
  INTERFACES_KERNEL	+= rtc
endif
ifeq ("$(CONFIG_SCHED_APIC)","y")
  timer_IMPL		+= timer-apic
  timer_tick_IMPL	+= timer_tick-apic
endif
ifeq ("$(CONFIG_SCHED_HPET)","y")
  timer_IMPL		+= timer-hpet
  timer_tick_IMPL       += timer_tick-single-vector timer_tick-ia32
  INTERFACES_KERNEL     += hpet
endif

ifeq ("$(CONFIG_JDB)","y")
JDB			:= jdb_compound.o
SUBSYSTEMS		+= JDB
INTERFACES_JDB		+= jdb_io_ports jdb_ptab jdb_trace_set \
			   jdb_console_buffer loadcnt jdb_io_apic \
			   jdb_bt jdb_log jdb_iomap jdb_misc \
			   jdb_halt_thread

CXXSRC_JDB := tb_entry_output.cc

apic_IMPL		+= apic-debug
jdb_IMPL		+= jdb-ia32
jdb_bp_IMPL		:= jdb_bp-ia32 jdb_bp-ia32-32
jdb_bt_IMPL		:= jdb_bt-ia32
jdb_entry_frame_IMPL	:= jdb_entry_frame-ia32
jdb_kern_info_IMPL	:= jdb_kern_info jdb_kern_info-ia32 jdb_kern_info-apic \
			   jdb_kern_info-pci jdb_kern_info-bench \
			   jdb_kern_info-bench-ia32-32 \
			   jdb_kern_info-dr jdb_kern_info-mtrr
jdb_misc_IMPL		:= jdb_misc-ia32
jdb_ptab_IMPL		:= jdb_ptab jdb_ptab-ia32
jdb_screen_IMPL		:= jdb_screen jdb_screen-ia32
jdb_tcb_IMPL		+= jdb_tcb-ia32
jdb_trace_set_IMPL	:= jdb_trace_set jdb_trace_set-ia32
jdb_tbuf_fe_IMPL	:= jdb_tbuf_fe jdb_tbuf_fe-ia32

INTERFACES_JDB		+= $(INTERFACES_JDB-y)
endif


CXXSRC_KERNEL		:= kernel_panic.cc libc_backend_lock.cc
ASSRC_KERNEL		:= entry.S entry-native.S sys_call_page-asm.S \
			   kip-time.S

ASSRC_KERNEL-$(CONFIG_MP)               += tramp-mp.S entry-mp.S
ASSRC_KERNEL-y                          += tramp-realmode.S tramp-acpi.S
ASSRC_KERNEL-$(CONFIG_CPU_VIRT)         += vm_svm_asm.S vm_vmx_asm.S
ASSRC_KERNEL                            += $(ASSRC_KERNEL-y)

NOOPT			+= $(filter jdb%,\
			     $(foreach in,$(INTERFACES_KERNEL), \
			       $(if $($(in)_IMPL),$($(in)_IMPL),$(in))))
NOOPT			+= tb_entry_output $(tb_entry_IMPL) $(perf_cnt_IMPL)  \
			   kern_cnt loadcnt $(apic_IMPL) $(watchdog_IMPL) kdb \
			   $(kernel_uart_IMPL) push_console virq thread-dbf   \
			   trap_state
NOOPT			+= $(foreach in,$(INTERFACES_JDB), \
			       $(if $($(in)_IMPL),$($(in)_IMPL),$(in)))


#
# CRT0 subsystem
#
CRT0 			:= crt0.o
ASSRC_CRT0		:= crt0.S

#
# BOOT subsystem
#
BOOT			:= fiasco
VPATH			+= boot/$(CONFIG_XARCH) boot
PRIVATE_INCDIR 		+= boot boot/ia32
CXXSRC_BOOT		:= boot_libc_glue.cc bootstrap.cc boot_cpu.cc \
			   direct_cons_putchar.cc
ASSRC_BOOT		:= boot.S boot_idt.S
NOOPT			+= $(patsubst %.o, %, $(OBJ_BOOT))

#
# TCBOFFSET subsystem
#
TCBOFFSET		:= tcboffset.h
CXXSRC_TCBOFFSET	:= tcboffset.cc dump_tcboffsets.cc

#
# SYMBOLS subsystem
#
SYMBOLS			:= Symbols

#
# CHECKSUM subsystem
#
CHECKSUM		:= checksum_subsys

#
# VERSION subsystem
#
VERSION			:= version.h

#
# GBLCFG subsystem
#
GBLCFG			:= gblcfg.o
OBJ_KERNEL		+= gblcfg.o

#
# CXXLIB Subsystem
#

CXXLIB			:= libcxx.a
VPATH			+= lib/cxxlib
CXXSRC_CXXLIB		:= paranoia.cc

#
# LIBK subsystem
#
LIBK		:= libk.a
VPATH		+= lib/libk/$(CONFIG_XARCH) lib/libk
PRIVATE_INCDIR  += lib/libk/$(CONFIG_XARCH) lib/libk
INTERFACES_LIBK	:= atomic lock_guard std_macros
CSRC_LIBK	+= gcc_lib.c
CXXSRC_LIBK     += construction.cc
atomic_IMPL     := atomic atomic-ia32

#
# LIBGZIP subsystem (only for Jdb)
#
ifneq ($(CONFIG_JDB_GZIP),)
  LIBGZIP		:= libgzip.a
  VPATH			+= lib/gzip
  PRIVATE_INCDIR	+= lib/gzip
  CSRC_LIBGZIP		:= adler32.c crc32.c gzip.c trees.c deflate.c zutil.c
  NOOPT			+= $(patsubst %.o, %, $(OBJ_LIBGZIP))
  $(foreach f, adler32 crc32 deflate trees zutil, \
    $(eval CFLAGS_$(f) += $(WNO_DEPRECATED_NON_PROTOTYPE) \
      -Wno-old-style-definition -Wno-strict-prototypes))
endif

# SIMPLEMALLOC
#
SIMPLEMALLOC       := libsimple_malloc.a
VPATH              += lib/simple_malloc
PRIVATE_INCDIR     += lib/simple_malloc
CXXSRC_SIMPLEMALLOC = simple_malloc.cc

#
# LIBDISASM subsystem (only for Jdb)
#
ifeq ("$(CONFIG_JDB_DISASM)","y")
  # $(srcdir)/lib/disasm may be removed
  ifeq ($(wildcard $(srcdir)/lib/disasm),)
    $(error $(srcdir)/lib/disasm is missing, disable CONFIG_JDB_DISASM)
  endif

  SUBSYSTEMS        += LIBDISASM
  KERNEL_EXTRA_LIBS += $(LIBDISASM)
  PREPROCESS_PARTS  += jdb_disasm

  LIBDISASM         := libdisasm.a
  VPATH             += lib/disasm lib/disasm/capstone \
                       lib/disasm/capstone/arch/X86
  PRIVATE_INCDIR    += lib/disasm lib/disasm/capstone/include
  CXXSRC_LIBDISASM  := disasm.cc
  CSRC_LIBDISASM    := cs.c utils.c \
                       MCInst.c MCInstrDesc.c MCRegisterInfo.c SStream.c
  CSRC_LIBDISASM    += X86Module.c X86Disassembler.c X86DisassemblerDecoder.c \
                       X86Mapping.c X86IntelInstPrinter.c X86ATTInstPrinter.c
  CPPFLAGS          += -DCAPSTONE_HAS_X86
  CFLAGS_cs              = -Wno-unused-parameter
  CFLAGS_SStream         = -Wno-unused-parameter
  CFLAGS_X86Mapping      = -Wno-unused-parameter -Wno-missing-field-initializers
  CFLAGS_X86Disassembler = -Wno-unused-parameter
  CFLAGS_X86IntelInstPrinter = -Wno-unused-parameter -Wno-sign-compare
  CFLAGS_X86ATTInstPrinter   = -Wno-unused-parameter -Wno-sign-compare
  CFLAGS_X86DisassemblerDecoder = -Wno-bad-function-cast
endif

#
# LIBPERFCTR subsystem (only for Jdb)
#
LIBPERFCTR	:= libperfctr.a
VPATH		+= lib/perfctr
PRIVATE_INCDIR	+= lib/perfctr
CSRC_LIBPERFCTR	:= event_set_p5.c event_set_p6.c event_set_amd.c \
		   event_set_p4.c event_set_x86.c perfctr.c \
		   event_set_centaur.c
NOOPT		+= $(patsubst %.o, %, $(OBJ_LIBPERFCTR))

#
# LIBREGEX subsystem (only for Jdb)
#
LIBREGEX	:= libregex.a
VPATH		+= lib/regex
PRIVATE_INCDIR	+= lib/regex
CSRC_LIBREGEX	:= rx.c
NOOPT		+= $(patsubst %.o, %, $(OBJ_LIBREGEX))

ifeq ("$(CONFIG_JDB)","y")

ifneq ($(CONFIG_JDB_GZIP),)
 ifneq ($(wildcard $(srcdir)/lib/gzip),)
  SUBSYSTEMS		+= LIBGZIP
  KERNEL_EXTRA_LIBS	+= $(LIBGZIP)
  INTERFACES_KERNEL	+= jdb_gzip
 endif
endif

ifneq ($(wildcard $(srcdir)/lib/perfctr),)
  SUBSYSTEMS		+= LIBPERFCTR
  KERNEL_EXTRA_LIBS	+= $(LIBPERFCTR)
  KERNEL_UNRES_SYMS	+= -u perfctr_set_cputype
endif

ifneq ($(wildcard $(srcdir)/lib/regex),)
  SUBSYSTEMS		+= LIBREGEX
  KERNEL_EXTRA_LIBS	+= $(LIBREGEX)
  PREPROCESS_PARTS	+= jdb_regex
endif

ifneq ($(filter LIBREGEX LIBDISASM,$(SUBSYSTEMS)),)
  SUBSYSTEMS          += SIMPLEMALLOC
  KERNEL_EXTRA_LIBS   += $(SIMPLEMALLOC)
endif

endif

MODULES_FILES += $(MODULES_FILE) $(MODULES_FILE_BSP)

INTERFACES_KERNEL       += $(INTERFACES_KERNEL-y)
